#include "drv_usart.h"
#include "dev_led.h"
#include "drv_fan.h"
#include "drv_motor.h"
#include "drv_deep.h"

uint8_t cmd_buffer[CMD_BUFFER_SIZE]={0};
uint16_t cmd_len=0;                 // 当前指令长度
uint16_t cmd_flag=0;

//USART实现串口调试工具间的通信，以控制设备
void drv_USART6_init(void)
{
	GPIO_InitTypeDef GPIO_InitStruct;
	USART_InitTypeDef USART_InitStruct;
	NVIC_InitTypeDef NVIC_InitStruct;//misc.c

	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOG,ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART6,ENABLE);
	
	GPIO_InitStruct.GPIO_Pin=GPIO_Pin_9|GPIO_Pin_14;
	GPIO_InitStruct.GPIO_Mode=GPIO_Mode_AF;
	GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_InitStruct.GPIO_OType=GPIO_OType_PP;
	GPIO_InitStruct.GPIO_PuPd=GPIO_PuPd_UP;
	
	//指定引脚复用的具体功能为USART6
	GPIO_PinAFConfig( GPIOG, GPIO_PinSource9, GPIO_AF_USART6);
    GPIO_PinAFConfig( GPIOG, GPIO_PinSource14,GPIO_AF_USART6);
	
	GPIO_Init(GPIOG, &GPIO_InitStruct);

	USART_InitStruct.USART_BaudRate=115200;//波特率
	//USART_HardwareFlowControl是 STM32 标准库中用于配置 USART（通用同步异步收发器）硬件流控制模式的参数，
	//用于控制串行通信中数据传输的流量，避免因接收方处理不及时导致的数据丢失。
	USART_InitStruct.USART_HardwareFlowControl=USART_HardwareFlowControl_None;
	USART_InitStruct.USART_Mode=USART_Mode_Rx | USART_Mode_Tx;
	//SART_Parity 用于配置 USART 通信的奇偶校验模式，是一种简单的错误检测机制。
	USART_InitStruct.USART_Parity=USART_Parity_No;
	USART_InitStruct.USART_StopBits=USART_StopBits_1;
	USART_InitStruct.USART_WordLength=USART_WordLength_8b;
	USART_Init(USART6, &USART_InitStruct);

	USART_ITConfig(USART6, USART_IT_RXNE,ENABLE);//开启接收中断
	//配置中断
	NVIC_InitStruct.NVIC_IRQChannel=USART6_IRQn;
	NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority=2;
	NVIC_InitStruct.NVIC_IRQChannelSubPriority=0;
	NVIC_InitStruct.NVIC_IRQChannelCmd=ENABLE;
	NVIC_Init(&NVIC_InitStruct);
	
	USART_ClearFlag(USART6, USART_FLAG_TC);
	USART_Cmd(USART6, ENABLE);
	
}

//重构fput函数，使用我写的代替C库里的fput函数
int fputc(int ch,FILE *f)
{
	USART_SendData(USART6,ch);
	while(USART_GetFlagStatus(USART6, USART_FLAG_TC)==RESET);
	USART_ClearFlag(USART6, USART_FLAG_TC);
	return ch;
}


// 解析并执行指令
void ExecuteCommand(void)
{
	if(cmd_flag)
	{
	// 比较指令
    if (strcmp((char*)cmd_buffer, "fan on") == 0) {
        drv_fan_open();
        printf("Fan turned on\r\n");
		
    } 
    else if (strcmp((char*)cmd_buffer, "fan off") == 0) {
        drv_fan_close();
        printf("Fan turned off\r\n");
    }
    else if (strcmp((char*)cmd_buffer, "beep on") ==0) {
        drv_deep_open();
        printf("Beep turned on\r\n");
    }
    else if (strcmp((char*)cmd_buffer, "beep off") ==0) {
        drv_deep_close();
        printf("Beep turned off\r\n");
    }
    else if (strcmp((char*)cmd_buffer, "led on") ==0) {
        dev_led_open();
        printf("LED turned on\r\n");

    }
    else if (strcmp((char*)cmd_buffer, "led off") ==0) {
        dev_led_close();
        printf("LED turned off\r\n");

    }
	else if (strcmp((char*)cmd_buffer, "motor on") ==0) {
        drv_motor_open();
        printf("Motor turned on\r\n");

    }
    else if (strcmp((char*)cmd_buffer, "motor off")==0) {
        drv_motor_close();
        printf("Motor turned off\r\n");

    }
	else {
        printf("未知指令!\r\n可用指令: fan on/off, beep on/off, led on/off, motor on/off\r\n");

    }
	// 清空缓冲区，准备接收新指令
		memset(cmd_buffer, 0, CMD_BUFFER_SIZE);
		cmd_len = 0;
		cmd_flag=0;
	
}
}

void USART6_IRQHandler(void)
{
	uint8_t recv_byte;
	if(USART_GetITStatus(USART6,USART_IT_RXNE)!= RESET)
	{
		USART_ClearITPendingBit(USART6, USART_IT_RXNE);//用于清除 USART 中断挂起标志位的函数
		recv_byte=USART_ReceiveData(USART6);
		//USART_SendData(USART6, recv_byte);//串口发送调试根据上接收到的数据

		//while (USART_GetFlagStatus(USART6,USART_FLAG_TXE) == RESET);
        
        // 处理接收的字节
        if (recv_byte == '\r'||recv_byte == '\n')
		{
            // 遇到回车或换行，说明一条指令接收完成
            if (cmd_len > 0) {
				
                cmd_flag=1;
            }
        } 
		else {
            // 将字符存入缓冲区（防止溢出）
            if (cmd_len < CMD_BUFFER_SIZE - 1) {
                cmd_buffer[cmd_len++] = recv_byte;
				//USART_SendData(USART6, cmd_buffer[6]);
				//printf("cmd_buffer: %c, cmd_len: %d\r\n", recv_byte, cmd_len);
            } else {
                cmd_len=0;
				memset(cmd_buffer, 0, CMD_BUFFER_SIZE);
            }
        }
	}
}






